import axios from 'axios'
// 导入vuex
import store from '../store'

// 导入JSON-big
import JSONBig from 'json-bigint'

// 创建一个全新的axios对象，并设置基地址
let instance = axios.create({

  baseURL: 'http://toutiao-app.itheima.net/',
  // 把基地址变了即可
  // baseURL: 'http://localhost:8000',
  // 我们这句话是为了转换响应体： request 请求的意思 response才是响应的意思
  transformResponse: [function (data) {

    try {

      // 用JSONBig来转换
      return JSONBig.parse(data)

    }catch {

      // 如果不是JSON就返回原本的响应体
      return data
    }
  }]
})


// 添加请求拦截器
instance.interceptors.request.use(function (config) {

  // 在发送请求之前做些什么
  // 这个config就是请求的参数，里面包含请求的路径、请求的方式等等
  // console.log('发请求的时候调用', config)
  // 最终config长什么样，你return出来，发的请求就是什么样
  // 证明了config我可以改，我改成什么样，它发出来的请求就是什么样
  // config.headers.zzzxxx = '32323232'
  // token存在哪？存在vuex里，但是我在这里能通过 this.$store来访问vuex吗？
  // 不能，所以要访问vuex还得导入vuex的实例

  // 获取存在vuex里的token
  let token = store.state.token.token

  // 如果是我第一次访问网站，肯定不会有token，所以应该判断一下
  // 如果有token再加token，没token就不加
  if (token) {
    config.headers.Authorization = 'Bearer ' + token
  }

  return config;

}, function (error) {

  // console.log('发请求有错误时调用')
  // 一般我们发请求时没什么错误，所以这里我们暂时用不上
  // 对请求错误做些什么
  return Promise.reject(error);
});


/*
// 添加响应拦截器
instance.interceptors.response.use(function (response) {
  // 这是正常响应调用的函数
  // response就是你axios发的请求拿到的结果
  // 所以response长什么样，你axios请求拿到的就是什么样
  console.log('响应拦截里打印的', response)
  response.xx = 'oo'
  // 对响应数据做点什么
  return response;

}, function (error) {

  // 这是错误响应调用的函数
  // 到时候我们要判断是不是401错误，如果是就刷新token
  // error里包含了出错信息
  if (error.response.status == 401) {
    // 代表token有问题，那么我们就要用refresh_token来刷新新的token
    // 现在要发请求去刷新token，但是千万不要用instance来发，我们可以就用axios来发
    axios({
      url: 'http://toutiao-app.itheima.net/v1_0/authorizations',
      method: 'put',
      headers: {
        Authorization: 'Bearer ' + store.state.token.refresh_token
      }
    })
    .then ( res => {
      // 把返回的最新的token保存到vuex和本地存储就行了
      // console.log(res)
      store.commit('saveToken', {
        token: res.data.data.token,
        refresh_token: store.state.token.refresh_token
      })

      // 拿到最新的token再发一个你之前要发的请求
      // error.config 这里面就保存了你之前发请求的相关配置
      // console.dir(error)
      // 所以我们按这个配置再发一次请求即可
      instance(error.config)
        .then (res => {

          // console.log('401错误后又请求得到的结果', res)
          // 我现在这么返回有用吗？？？
          return res
        })
    })
  }
  // 对响应错误做点什么
  return Promise.reject(error);
});

*/

import { Toast } from 'vant'
import router from '../router'
// 添加响应拦截器
instance.interceptors.response.use(function (response) {
  // 这是正常响应调用的函数
  // response就是你axios发的请求拿到的结果
  // 所以response长什么样，你axios请求拿到的就是什么样
  // console.log('响应拦截里打印的', response)
  response.xx = 'oo'
  // 对响应数据做点什么
  return response;

}, async function (error) {

  // 这是错误响应调用的函数
  // 到时候我们要判断是不是401错误，如果是就刷新token
  // error里包含了出错信息
  if (error.response.status == 401) {
    // 代表token有问题，那么我们就要用refresh_token来刷新新的token
    // 现在要发请求去刷新token，但是千万不要用instance来发，我们可以就用axios来发
    // 我们给instance加过请求拦截，在请求拦截里都会重新带入Authorization这个值
    // 就意味着它又拿原来失效的token来发这次请求
    try {
      let res = await axios({
        url: 'http://toutiao-app.itheima.net/v1_0/authorizations',
        method: 'put',
        headers: {
          Authorization: 'Bearer ' + store.state.token.refresh_token
        }
      })

      // 把返回的最新的token保存到vuex和本地存储就行了
      store.commit('saveToken', {
        token: res.data.data.token,
        refresh_token: store.state.token.refresh_token
      })
      // 拿到最新的token再发一个你之前要发的请求
      // error.config 这里面就保存了你之前发请求的相关配置
      // console.dir(error)
      // 所以我们按这个配置再发一次请求即可
      let res2 = instance(error.config)
      return res2
    }
    catch {

      // 给用户提示，登录状态已过期请重新登录
      Toast.fail('登录状态已过期，请重新登录')
      // 跳转回登录页
      router.push('/login')
    }
  }
  // 对响应错误做点什么
  return Promise.reject(error);
});



// 把请求对象暴露出去
export default instance